local ver,debool="1.2",false
local throttle,filter,filterRanges,money=0


local function Debug(...)
	if debool then
		print("Debug:",...)
	end
end


Cashier=CreateFrame("frame")

-- parsing function             OF DOOOOOOOOM
function Cashier:ParseMoney(val)
	if val==0 then
		return
	end
	
	if filterRanges then
		for _,v in pairs(filterRanges) do
			if not strmatch(filter,"/addup") then
				money=GetMoney()
			end
			Debug(v.from.."<"..(v.incf and "=" or "")..val.."<"..(v.inct and "=" or "")..v.to..": "..tostring((v.incf and val>=v.from or val>v.from) and (v.inct and val<=v.to or val<v.to)))
			if (v.incf and val>=v.from or val>v.from) and (v.inct and val<=v.to or val<v.to) then
				return
			end
		end
	else
		Debug(val)
	end
	local msg
	if val<0 then
		val=-val
		msg=self.lose
	else
		msg=self.gain
	end
	local c,s,g=val%100,math.floor(val/100)%100,math.floor(val/10000)
	if g==0 then
		msg=gsub(msg,"%[[^%]]-%%g.-%]","")
		if s==0 then
			msg=gsub(msg,"%[[^%]]-%%s.-%]","")
		end
	end
	if self.hideZeroValues then
		if s==0 then
			msg=gsub(msg,"%[[^%]]-%%s.-%]","")
		end
		if c==0 then
			msg=gsub(msg,"%[[^%]]-%%c.-%]","")
		end
	elseif self.hideEndZeroValues then
		if c==0 then
			msg=gsub(msg,"%[[^%]]-%%c.-%]","")
			if s==0 then
				msg=gsub(msg,"%[[^%]]-%%s.-%]","")
			end
		end
	end
	if self.leadingZero then
		if val>99 then
			if c<10 then
				c="0"..c
			end
			if val>9999 then
				if s<10 then
					s="0"..s
				end
			end
		end
	end
	msg=gsub(msg,"%[(.-%%[gsc].-)%]","%1")
	msg=gsub(msg,"%%g",g)
	msg=gsub(msg,"%%s",s)
	msg=gsub(msg,"%%c",c)
	money=GetMoney()
	return msg
end


Cashier:SetScript("OnEvent",function(self,event,...)
	Debug(event)
	if self[event] then
		return self[event](self,event,...)
	elseif	strfind(event,"_SHOW$") then
		self:ChangeSettings(self.settings[strmatch(event,"(.*)_SHOW$")])
	elseif strfind(event,"_CLOSED$") then
		self:ChangeSettings(self.settings.general)
	end
end)

function Cashier:ChangeSettings(setting)
	--			BLOCKING
	
	if setting.block then
		self:UnregisterEvent("PLAYER_MONEY")
		return
	else
		if not self:IsEventRegistered("PLAYER_MONEY") then
			self:RegisterEvent("PLAYER_MONEY")
			self:PLAYER_MONEY()
		end
	end
	
	--			FILTER
	
	local newFilter
	if setting.filter then
		newFilter=filter~=setting.filter
		filter=setting.filter
	else
		newFilter=filter~=self.settings.general.filter
		filter=self.settings.general.filter
	end
	
	if newFilter then
		Debug(filter)
		filterRanges={}
		local ranges={strsplit("U",filter)}
		for _,v in pairs(ranges) do
			if not strmatch(v,"([%(%[])(-?%d+);(-?%d+)([%)%]])") then
				error("Cashier: Malformed filter.")
				return
			end
			local incf,from,to,inct=strmatch(v,"([%(%[])(-?%d+);(-?%d+)([%)%]])")
			incf=incf=="["
			inct=inct=="]"
			from=tonumber(from)
			to=tonumber(to)
			if to<from then
				incf,from,to,inct=inct,to,from,incf
			end
			tinsert(filterRanges,{incf=incf,from=from,to=to,inct=inct})
		end
	end
	
	--			THROTTLING
	
	if type(setting.throttle)=="number" and setting.throttle>0 then
		self:UnregisterEvent("PLAYER_MONEY")
		self:SetScript("OnUpdate",function(self,elap)
			if throttle>0 then
				throttle=throttle-elap
			else
				throttle=throttle+setting.throttle
				self:PLAYER_MONEY()
			end
		end)
	else
		self:SetScript("OnUpdate",function()end)
	end
end


Cashier:RegisterEvent("ADDON_LOADED")

function Cashier:ADDON_LOADED(event,addon)
	if addon=="Cashier" then
		self:UnregisterEvent("ADDON_LOADED")
		self.ADDON_LOADED=nil

		if IsLoggedIn()then
			self:PLAYER_LOGIN()
		else
			self:RegisterEvent("PLAYER_LOGIN")
		end
	end
end


function Cashier:PLAYER_LOGIN()
	self:RegisterEvent("PLAYER_MONEY")
	
	-- register the events for all the settings we need to
	for k,v in pairs(self.settings) do
		if v then
			self:RegisterEvent(k.."_SHOW")
			self:RegisterEvent(k.."_CLOSED")
		end
	end
	
	-- add the colors/icons to the message format strings
	
	-- wow giveth
	while strfind(self.gain,"%%[gsc][:ci]-[ %]]") do
		local moneyKind,option1,option2=strsplit(":",strmatch(self.gain,"%%([gsc][:ci]-)[ %]]"))
		if option1=="c" or option2=="c" then
			self.gain=gsub(self.gain,"(%%"..moneyKind..".-)([ %]])","|c"..self.colors[moneyKind].."%1|r%2")
		end
		if option1=="i" or option2=="i" then
			self.gain=gsub(self.gain,"(%%"..moneyKind..".-)([ %]])","%1|T"..self.icons[moneyKind]..":12|t%2")
		end
		self.gain=gsub(self.gain,"(%%"..moneyKind..")[:ci]+","%1")
	end	
	-- wow taketh
	while strfind(self.lose,"%%[gsc][:ci]-[ %]]") do
		local moneyKind,option1,option2=strsplit(":",strmatch(self.lose,"%%([gsc][:ci]-)[ %]]"))
		if option1=="c" or option2=="c" then
			self.lose=gsub(self.lose,"(%%"..moneyKind..".-)([ %]])","|c"..self.colors[moneyKind].."%1|r%2")
		end
		if option1=="i" or option2=="i" then
			self.lose=gsub(self.lose,"(%%"..moneyKind..".-)([ %]])","%1|T"..self.icons[moneyKind]..":12|t%2")
		end
		self.lose=gsub(self.lose,"(%%"..moneyKind..")[:ci]+","%1")
	end
	
	
	money=GetMoney()
	self:ChangeSettings(self.settings.general)
	
	self:UnregisterEvent("PLAYER_LOGIN")
	self.PLAYER_LOGIN=nil
end

function Cashier:PLAYER_MONEY()
	DEFAULT_CHAT_FRAME:AddMessage(self:ParseMoney(GetMoney()-money))
end

local function MoneyFilter(self,event,msg,...)
	if event=="CHAT_MSG_SYSTEM" then
		if strfind(msg,gsub(ERR_QUEST_REWARD_MONEY_S,"%%s",".*")) and not(strfind(msg,gsub(ERR_QUEST_REWARD_ITEM_MULT_IS,"%%[ds]",".*")) or strfind(msg,gsub(ERR_QUEST_REWARD_ITEM_S,"%%s",".*"))) then
			return true
		end
	elseif event=="CHAT_MSG_MONEY" then
		if strfind(msg,gsub(LOOT_MONEY_SPLIT,"%%s",".*")) or strfind(msg,gsub(YOU_LOOT_MONEY,"%%s",".*")) then
			return true
		end
	end
end
ChatFrame_AddMessageEventFilter("CHAT_MSG_SYSTEM",MoneyFilter)
ChatFrame_AddMessageEventFilter("CHAT_MSG_MONEY",MoneyFilter)